﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using System.Drawing;
using System.Collections;
using DBLibrary;
using System.Collections.ObjectModel;

namespace WPFClient
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        protected ImageCollection imageCollection1 { get; set; }
        protected ImageCollection imageCollection2 { get; set; }
        protected ListBox dragSource = null;

        private Customer customer;
        private string drag;

        public MainWindow(Customer customer)
        {
            InitializeComponent();

            this.customer = customer;

            // Fill the comboBox with the customer's albums
            //
            fillComboBox();

            // Instiantiate imageCollections
            //
            imageCollection1 = new ImageCollection();
            imageCollection2 = new ImageCollection();

            // Bind the collection to the ObjectDataProvider
            //
            ObjectDataProvider imageSource = (ObjectDataProvider)FindResource("ImageCollection1");
            imageSource.ObjectInstance = imageCollection1;
            imageSource = (ObjectDataProvider)FindResource("ImageCollection2");
            imageSource.ObjectInstance = imageCollection2;

            // Fill imageCollection2
            //
            string[] PNGfiles = Directory.GetFiles(@"C:\Users\user\Pictures\test", "*.png", SearchOption.TopDirectoryOnly);
            string[] JPGfiles = Directory.GetFiles(@"C:\Users\user\Pictures\test", "*.jpg", SearchOption.TopDirectoryOnly);

            foreach (string png in PNGfiles)
                imageCollection2.Add(new ImageObject(fromPathToFile(png), imageToByteArray(System.Drawing.Image.FromFile(png))));
            foreach (string jpg in JPGfiles)
                imageCollection2.Add(new ImageObject(fromPathToFile(jpg), imageToByteArray(System.Drawing.Image.FromFile(jpg))));
        }

        // Fill the comboBox with the customer's albums
        public void fillComboBox()
        {
            this.AlbumIDs.Items.Clear();
            List<Album> albums = customer.getCustomersAlbums();
            foreach (Album a in albums)
            {
                AlbumIDs.Items.Add(a);
            }
        }

        private string fromPathToFile(string path)
        {
            string[] words = path.Split('\\');
            return words[words.Length - 1];
        }

        private byte[] imageToByteArray(System.Drawing.Image imageIn)
        {
            MemoryStream ms = new MemoryStream();
            imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            return ms.ToArray();
        }

        // On initie le Drag and Drop
        private void ImageDragEvent(object sender, MouseButtonEventArgs e)
        {
            ListBox parent = (ListBox)sender;
            drag = parent.Name;
            dragSource = parent;
            object data = GetDataFromListBox(dragSource, e.GetPosition(parent));
            if (data != null)
            {
                DragDrop.DoDragDrop(parent, data, DragDropEffects.Move);
            }
        }

        /// <summary>
        /// Drop an object from a listbox to an other listbox
        /// </summary>
        private void ImageDropEvent(object sender, DragEventArgs e)
        {
            ListBox parent = (ListBox)sender;
            ImageObject data = (ImageObject)e.Data.GetData(typeof(ImageObject));

            // Upload case
            //
            if (parent.Name == "ListBox1" && drag == "ListBox2")
            {
                Album a = (Album)AlbumIDs.SelectedItem;
                if (a == null) return;

                // Instanciation of the TransfertImageClient service reference
                //
                TransfertImageService.TransfertImageClient imageTransfertService = new TransfertImageService.TransfertImageClient();
                TransfertImageService.ImageInfo imageInfo = new TransfertImageService.ImageInfo();
                imageInfo.IDAlbum = a.Id;
                MemoryStream imageStream = new MemoryStream(data.Image);
                
                // Call web method
                //
                imageTransfertService.uploadImage(imageInfo, imageStream);

                ((IList)parent.ItemsSource).Add(data);
            }
            // Download case
            //
            else if(parent.Name == "ListBox2" && drag == "ListBox1")
            {
                // Instanciation of the TransfertImageClient service reference
                //
                TransfertImageService.TransfertImageClient imageTransfertService = new TransfertImageService.TransfertImageClient();
                TransfertImageService.ImageInfo imageInfo = new TransfertImageService.ImageInfo();

                imageInfo.ID = int.Parse(data.Name);
                Stream image = imageTransfertService.downloadImage(imageInfo);
                MemoryStream ms = new MemoryStream(fromStreamToByteArray(image));

                // Save the image
                //
                FileStream file = new FileStream(@"C:\Users\user\Pictures\test\" + imageInfo.ID.ToString() + ".png", FileMode.Create, System.IO.FileAccess.Write);
                byte[] bytes = new byte[ms.Length];
                ms.Read(bytes, 0, (int)ms.Length);
                file.Write(bytes, 0, bytes.Length);
                file.Close();
                ms.Close();

                ((IList)parent.ItemsSource).Add(data);
            }
        }

        // On récupére l'objet que que l'on a dropé
        private static object GetDataFromListBox(ListBox source, System.Windows.Point point)
        {
            UIElement element = (UIElement)source.InputHitTest(point);
            if (element != null)
            {
                object data = DependencyProperty.UnsetValue;
                while (data == DependencyProperty.UnsetValue)
                {
                    data =
                    source.ItemContainerGenerator.ItemFromContainer(element);
                    if (data == DependencyProperty.UnsetValue)
                    {
                        element = (UIElement)VisualTreeHelper.GetParent(element);
                    }
                    if (element == source)
                    {
                        return null;
                    }
                }
                if (data != DependencyProperty.UnsetValue)
                {
                    return data;
                }
            }
            return null;
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ((ObservableCollection<ImageObject>)ListBox1.ItemsSource).Clear();
            Album album = (Album)AlbumIDs.SelectedItem;
            List<int> imageIDs = customer.getImageIdByAlbum(album.Id);
            TransfertImageService.TransfertImageClient client = new TransfertImageService.TransfertImageClient();
            TransfertImageService.ImageInfo info = new TransfertImageService.ImageInfo();

            foreach (int id in imageIDs)
            {
                info.ID = id;
                Stream image = client.downloadImage(info);
                imageCollection1.Add(new ImageObject(id.ToString(), fromStreamToByteArray(image)));
            }
        }

        /// <summary>
        /// Change a stream in a byte array
        /// </summary>
        /// <param name="stream">The stream to change</param>
        /// <returns>Returns a Byte array</returns>
        private static byte[] fromStreamToByteArray(System.IO.Stream stream)
        {
            long originalPosition = 0;

            if (stream.CanSeek)
            {
                originalPosition = stream.Position;
                stream.Position = 0;
            }

            try
            {
                byte[] readBuffer = new byte[4096];

                int totalBytesRead = 0;
                int bytesRead;

                while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                {
                    totalBytesRead += bytesRead;

                    if (totalBytesRead == readBuffer.Length)
                    {
                        int nextByte = stream.ReadByte();
                        if (nextByte != -1)
                        {
                            byte[] temp = new byte[readBuffer.Length * 2];
                            Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                            Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                            readBuffer = temp;
                            totalBytesRead++;
                        }
                    }
                }

                byte[] buffer = readBuffer;
                if (readBuffer.Length != totalBytesRead)
                {
                    buffer = new byte[totalBytesRead];
                    Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                }
                return buffer;
            }
            finally
            {
                if (stream.CanSeek)
                {
                    stream.Position = originalPosition;
                }
            }
        }

        private void buttonAddAlbum_Click(object sender, RoutedEventArgs e)
        {
            AddAlbum add = new AddAlbum(customer);
            add.Show();
        }
    }
}
